﻿(*  
    F# Dataflow for ViewModels
    (c) Andras Janko, 2013, Available under Microsoft Public License.
*)

module private FsFlow.Core

open System
open System.Collections.Specialized
open System.ComponentModel

let mutable needsRefresh = Set.empty<IPath>
let mutable deferred = false
let mutable refreshInProgress = false

let inline addToRefresh b = needsRefresh <- needsRefresh.Add b
let inline removeFromRefresh b = needsRefresh <- needsRefresh.Remove b

let refresh() =
    if not refreshInProgress && not deferred && not needsRefresh.IsEmpty then
        refreshInProgress <- true
        while not deferred && not needsRefresh.IsEmpty do
            let next = needsRefresh.MinimumElement                
            needsRefresh <- needsRefresh.Remove next
            next.Refresh()
        refreshInProgress <- false

let defer() =
    if deferred then { new IDisposable with member this.Dispose() = () } else
        deferred <- true
        refreshInProgress <- false
        { new IDisposable with
            member this.Dispose() =
                deferred <- false
                refresh() }

let mutable nextMappedTicket = Ticket.zero
let getMappedTicket() =
    let n = nextMappedTicket
    nextMappedTicket <- nextMappedTicket |> Ticket.nextId
    n    

let mutable nextCompTickets = Map.empty<byte, Ticket ref>

let getCompTicket level =
    let t =
        match nextCompTickets |> Map.tryFind level with
        | Some t -> t
        | None ->
            let t = Ticket.ofLevel level |> ref
            nextCompTickets <- nextCompTickets |> Map.add level t
            t
    fun () ->
        let n = !t
        t := n |> Ticket.nextId
        n

let propertiesChanged = PropertyChangedEventArgs null
let resetCollectionChanged = NotifyCollectionChangedEventArgs NotifyCollectionChangedAction.Reset
